package com.fsserver.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fsserver.common.constants.PaymentConstants;
import com.fsserver.common.exception.BusinessException;
import com.fsserver.core.dto.ReconciliationRequestDTO;
import com.fsserver.core.entity.Reconciliation;
import com.fsserver.core.mapper.ReconciliationMapper;
import com.fsserver.core.service.PaymentStrategy;
import com.fsserver.core.service.ReconciliationService;
import com.fsserver.core.vo.ReconciliationResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 对账服务实现类
 * Reconciliation Service Implementation
 *
 * @author fsserver
 */
@Slf4j
@Service
public class ReconciliationServiceImpl extends ServiceImpl<ReconciliationMapper, Reconciliation> implements ReconciliationService {

    @Autowired
    private Map<String, PaymentStrategy> paymentStrategyMap;

    /**
     * 创建对账
     * Create reconciliation
     *
     * @param reconciliationRequestDTO 对账请求DTO
     * @return 对账响应
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReconciliationResponseVO createReconciliation(ReconciliationRequestDTO reconciliationRequestDTO) {
        log.info("创建对账: {}", reconciliationRequestDTO);
        
        // 获取支付策略
        PaymentStrategy paymentStrategy = getPaymentStrategy(reconciliationRequestDTO.getPaymentType());
        
        // 创建对账
        Reconciliation reconciliation = createReconciliationEntity(reconciliationRequestDTO);
        
        // 调用支付策略创建对账
        ReconciliationResponseVO reconciliationResponseVO = paymentStrategy.createReconciliation(reconciliationRequestDTO, reconciliation);
        
        log.info("对账创建成功: {}", reconciliation.getReconciliationNo());
        return reconciliationResponseVO;
    }

    /**
     * 查询对账
     * Query reconciliation
     *
     * @param reconciliationNo 对账号
     * @return 对账
     */
    @Override
    public Reconciliation queryReconciliation(String reconciliationNo) {
        log.info("查询对账: {}", reconciliationNo);
        
        // 获取对账
        Reconciliation reconciliation = getOne(new LambdaQueryWrapper<Reconciliation>()
                .eq(Reconciliation::getReconciliationNo, reconciliationNo));
        
        if (reconciliation == null) {
            log.error("对账不存在: {}", reconciliationNo);
            throw new BusinessException("对账不存在");
        }
        
        return reconciliation;
    }

    /**
     * 根据支付类型查询对账列表
     * List reconciliations by payment type
     *
     * @param paymentType 支付类型
     * @return 对账列表
     */
    @Override
    public List<Reconciliation> listReconciliationsByPaymentType(String paymentType) {
        log.info("根据支付类型查询对账列表: {}", paymentType);
        
        return list(new LambdaQueryWrapper<Reconciliation>()
                .eq(Reconciliation::getPaymentType, paymentType)
                .orderByDesc(Reconciliation::getCreateTime));
    }

    /**
     * 根据日期范围查询对账列表
     * List reconciliations by date range
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 对账列表
     */
    @Override
    public List<Reconciliation> listReconciliationsByDateRange(Date startDate, Date endDate) {
        log.info("根据日期范围查询对账列表: {} - {}", startDate, endDate);
        
        return list(new LambdaQueryWrapper<Reconciliation>()
                .ge(Reconciliation::getReconciliationDate, startDate)
                .le(Reconciliation::getReconciliationDate, endDate)
                .orderByDesc(Reconciliation::getCreateTime));
    }

    /**
     * 执行对账
     * Execute reconciliation
     *
     * @param reconciliationNo 对账号
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean executeReconciliation(String reconciliationNo) {
        log.info("执行对账: {}", reconciliationNo);
        
        // 获取对账
        Reconciliation reconciliation = queryReconciliation(reconciliationNo);
        
        // 检查对账状态
        if (!PaymentConstants.ReconciliationStatus.INIT.equals(reconciliation.getStatus())) {
            log.error("对账状态不允许执行: {}, {}", reconciliationNo, reconciliation.getStatus());
            throw new BusinessException("对账状态不允许执行");
        }
        
        // 获取支付策略
        PaymentStrategy paymentStrategy = getPaymentStrategy(reconciliation.getPaymentType());
        
        // 调用支付策略执行对账
        boolean result = paymentStrategy.executeReconciliation(reconciliation);
        
        if (result) {
            // 更新对账状态
            reconciliation.setStatus(PaymentConstants.ReconciliationStatus.SUCCESS);
            // 设置对账时间 - 使用updateTime字段
            reconciliation.setUpdateTime(new Date());
            updateById(reconciliation);
        } else {
            // 更新对账状态
            reconciliation.setStatus(PaymentConstants.ReconciliationStatus.FAILED);
            updateById(reconciliation);
        }
        
        log.info("对账执行结果: {}, {}", reconciliationNo, result);
        return result;
    }
    
    /**
     * 创建对账实体
     * Create reconciliation entity
     *
     * @param reconciliationRequestDTO 对账请求DTO
     * @return 对账
     */
    private Reconciliation createReconciliationEntity(ReconciliationRequestDTO reconciliationRequestDTO) {
        // 创建对账
        Reconciliation reconciliation = new Reconciliation();
        reconciliation.setReconciliationNo(generateReconciliationNo());
        reconciliation.setPaymentType(reconciliationRequestDTO.getPaymentType());
        reconciliation.setReconciliationDate(reconciliationRequestDTO.getReconciliationDate());
        reconciliation.setStatus(PaymentConstants.ReconciliationStatus.INIT);
        // 设置备注，如果DTO中有这个字段
        if (reconciliationRequestDTO.getExtraParams() != null) {
            reconciliation.setRemarks(reconciliationRequestDTO.getExtraParams());
        }
        
        // 保存对账
        save(reconciliation);
        
        return reconciliation;
    }
    
    /**
     * 获取支付策略
     * Get payment strategy
     *
     * @param paymentType 支付类型
     * @return 支付策略
     */
    private PaymentStrategy getPaymentStrategy(String paymentType) {
        PaymentStrategy paymentStrategy = paymentStrategyMap.get(paymentType);
        if (paymentStrategy == null) {
            log.error("支付类型不支持: {}", paymentType);
            throw new BusinessException("支付类型不支持");
        }
        return paymentStrategy;
    }
    
    /**
     * 生成对账号
     * Generate reconciliation number
     *
     * @return 对账号
     */
    private String generateReconciliationNo() {
        // 生成对账号：RC + 时间戳 + 6位随机数
        return "RC" + System.currentTimeMillis() + String.format("%06d", (int) (Math.random() * 1000000));
    }
} 